from flask import request
from flask_restx import Resource, Namespace, fields
from app.utils.response import success_response, error_response, paginate_response
from app.utils.auth import token_required
from app.utils.validators import validate_required_fields
from app.services.role_service import RoleService
from app.services.menu_service import MenuService
from app.models.role import Role
from app.swagger_docs import (
    success_response_model, error_response_model, pagination_response_model,
    role_model
)

# 创建角色命名空间
role_ns = Namespace('roles', description='角色管理接口')

# 定义请求模型
role_create_model = role_ns.model('RoleCreate', {
    'name': fields.String(required=True, description='角色名称'),
    'description': fields.String(description='角色描述'),
    'data_scope': fields.String(description='数据权限范围'),
    'status': fields.Boolean(description='状态', default=True)
})

role_update_model = role_ns.model('RoleUpdate', {
    'name': fields.String(description='角色名称'),
    'description': fields.String(description='角色描述'),
    'data_scope': fields.String(description='数据权限范围'),
    'status': fields.Boolean(description='状态')
})

role_menu_request_model = role_ns.model('RoleMenuRequest', {
    'menu_ids': fields.List(fields.Integer, required=True, description='菜单ID列表')
})

role_permission_request_model = role_ns.model('RolePermissionRequest', {
    'id': fields.Integer(required=True, description='角色ID'),
    'menu': fields.List(fields.Integer, description='菜单ID列表'),
    'data_range': fields.Integer(description='数据权限范围 (0:本人, 1:本部门, 2:本部门及子部门, 3:全部, 4:自定义)')
})

@role_ns.route('/')
class RoleListAPI(Resource):
    """角色列表和新增接口"""
    
    @role_ns.doc(
        description='获取角色列表',
        security='Bearer',
        params={
            'page': '页码',
            'per_page': '每页数量',
            'keyword': '搜索关键词',
            'status': '状态筛选'
        },
        responses={
            200: ('获取成功', pagination_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin):
        """获取角色列表"""
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        keyword = request.args.get('keyword', '')
        status = request.args.get('status', type=int)
        
        if status is not None:
            status = bool(status)
        
        query, page, per_page = RoleService.get_list(page, per_page, keyword, status)
        return paginate_response(query, page, per_page)
    
    @role_ns.doc(
        description='创建新角色',
        security='Bearer',
        responses={
            200: ('创建成功', success_response_model),
            400: ('请求参数错误', error_response_model),
            401: ('未授权', error_response_model),
            500: ('服务器错误', error_response_model)
        }
    )
    @role_ns.expect(role_create_model, validate=True)
    @token_required
    def post(self, current_admin):
        """创建新角色"""
        # 验证必填字段
        is_valid, error_msg = validate_required_fields(['name'])
        if not is_valid:
            return error_response(error_msg, 400)
        
        data = request.get_json()
        
        try:
            role = RoleService.create(data)
            return success_response(role.to_dict(), '创建成功')
        except Exception as e:
            return error_response(f'创建失败：{str(e)}', 500)


@role_ns.route('/<int:role_id>')
class RoleDetailAPI(Resource):
    """角色详情、更新和删除接口"""
    
    @role_ns.doc(
        description='获取角色详情',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            404: ('角色不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin, role_id):
        """获取角色详情"""
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        return success_response(role.to_dict())
    
    @role_ns.doc(
        description='更新角色信息',
        security='Bearer',
        responses={
            200: ('更新成功', success_response_model),
            400: ('请求参数错误', error_response_model),
            404: ('角色不存在', error_response_model),
            401: ('未授权', error_response_model),
            500: ('服务器错误', error_response_model)
        }
    )
    @role_ns.expect(role_update_model)
    @token_required
    def put(self, current_admin, role_id):
        """更新角色信息"""
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        data = request.get_json()
        
        try:
            updated_role = RoleService.update(role_id, data)
            return success_response(updated_role.to_dict(), '更新成功')
        except Exception as e:
            return error_response(f'更新失败：{str(e)}', 500)
    
    @role_ns.doc(
        description='删除角色',
        security='Bearer',
        responses={
            200: ('删除成功', success_response_model),
            400: ('删除失败', error_response_model),
            404: ('角色不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def delete(self, current_admin, role_id):
        """删除角色"""
        result = RoleService.delete(role_id)
        if isinstance(result, tuple):
            success, message = result
            if not success:
                return error_response(message, 400)
            return success_response(message=message)
        else:
            if not result:
                return error_response('删除失败，角色不存在', 404)
            return success_response(message='删除成功')


@role_ns.route('/<int:role_id>/menus')
class RoleMenuAPI(Resource):
    """角色菜单权限接口"""
    
    @role_ns.doc(
        description='获取角色菜单权限配置数据',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            404: ('角色不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin, role_id):
        """获取角色菜单权限配置数据"""
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        # 获取完整菜单树结构（用于权限配置）
        menu_tree = MenuService.get_tree_for_permission()
        
        # 获取角色已选择的菜单ID
        role_menu_ids = RoleService.get_role_menus(role_id)
        
        data = {
            'menu_tree': menu_tree,
            'role_menu_ids': role_menu_ids or [],
            'role': role.to_dict()
        }
        
        return success_response(data)
    
    @role_ns.doc(
        description='保存角色菜单权限',
        security='Bearer',
        responses={
            200: ('设置成功', success_response_model),
            400: ('请求参数错误', error_response_model),
            404: ('角色不存在', error_response_model),
            401: ('未授权', error_response_model),
            500: ('设置失败', error_response_model)
        }
    )
    @role_ns.expect(role_menu_request_model, validate=True)
    @token_required
    def put(self, current_admin, role_id):
        """保存角色菜单权限"""
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        data = request.get_json()
        menu_ids = data.get('menu_ids', [])
        
        success = RoleService.set_role_menus(role_id, menu_ids)
        if not success:
            return error_response('设置失败', 500)
        
        return success_response(message='权限设置成功')


@role_ns.route('/permission')
class RolePermissionAPI(Resource):
    """角色权限保存接口（兼容旧的API）"""
    
    @role_ns.doc(
        description='保存角色权限配置（兼容旧的API）',
        security='Bearer',
        responses={
            200: ('设置成功', success_response_model),
            400: ('请求参数错误', error_response_model),
            404: ('角色不存在', error_response_model),
            401: ('未授权', error_response_model),
            500: ('设置失败', error_response_model)
        }
    )
    @role_ns.expect(role_permission_request_model, validate=True)
    @token_required
    def put(self, current_admin):
        """保存角色权限配置"""
        data = request.get_json()
        role_id = data.get('id')
        menu_ids = data.get('menu', [])
        data_scope = data.get('data_range')
        
        if not role_id:
            return error_response('角色ID不能为空', 400)
        
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        try:
            # 更新菜单权限
            if menu_ids is not None:
                RoleService.set_role_menus(role_id, menu_ids)
            
            # 更新数据权限范围
            if data_scope is not None:
                # 将前端的数字映射为后端的字符串
                scope_mapping = {
                    0: Role.DATA_SCOPE_SELF,
                    1: Role.DATA_SCOPE_DEPT,
                    2: Role.DATA_SCOPE_DEPT_AND_CHILD,
                    3: Role.DATA_SCOPE_ALL,
                    4: Role.DATA_SCOPE_CUSTOM
                }
                
                if data_scope in scope_mapping:
                    update_data = {'data_scope': scope_mapping[data_scope]}
                    RoleService.update(role_id, update_data)
            
            return success_response(message='权限设置成功')
        except Exception as e:
            return error_response(f'设置失败：{str(e)}', 500)


@role_ns.route('/data-scope-options')
class RoleDataScopeAPI(Resource):
    """角色数据权限选项接口"""
    
    @role_ns.doc(
        description='获取数据权限选项',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin):
        """获取数据权限选项"""
        data_scope_choices = Role.get_data_scope_choices()
        return success_response(data_scope_choices) 